package com.itisyue.fun.utils;

import com.itisyue.fun.dto.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

public class TransferUtil {
    static Logger log = LoggerFactory.getLogger(TransferUtil.class);
    public static String deleteLegalString(String content){
        String regEx = "[\\n`~!@#$%^&*()+=|{}':;',\\\\[\\\\]<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。， 、？]";
        return content.replaceAll(regEx,"");
    }
    //获取 文件名前缀或后缀
    public static String getLastFileNamePrefixOrSuffix(String fileName, Boolean prefix){
        //去除不合法文件名中的特殊字符
        fileName = deleteLegalString(fileName);
        String[] arr = fileName.split("\\.");
        if(prefix){//前缀
            String prefixStr = "";
            for(int i=0;i<arr.length-1;i++){
                prefixStr +=arr[i]+".";
            }
            return prefixStr.substring(0, prefixStr.length()-1);
        }else{
            //后缀
            return arr.length<=1?null:arr[arr.length-1];
        }
    }
    public static String getLastFileName(String fileName){
        int unixSep = fileName.lastIndexOf('/');
        int winSep = fileName.lastIndexOf('\\');
        int pos = (winSep > unixSep ? winSep : unixSep);
        if(pos != -1){
            fileName = fileName.substring(pos + 1);
        }
        fileName = TransferUtil.deleteLegalString(fileName);
        return fileName;
    }

    public static void reflectSetValue(Class<?> clz, Object obj, String filedName, String value){
        try{
            //获取改类的成员变量
            Field f = clz.getDeclaredField(filedName);
            //取消语言访问检查
            f.setAccessible(true);
            //给变量赋值
            f.set(obj,value);
        }catch (Exception e){
            try{
                //从继承类再拿一次
                Field declaredField = clz.getSuperclass().getDeclaredField(filedName);
                //取消语言访问检查
                declaredField.setAccessible(true);
                //给变量赋值
                declaredField.set(obj,value);
            }catch (Exception e1){
                String error = String.format("反射取值异常, error=%s", e1.getMessage());
                log.error(error, e1);
                throw new BusinessException(error);
            }
        }
    }
    public static <T> List<List<T>> splitListHandle(List<T> dataList, int limit){
        List<List<T>> splitedList = new ArrayList<>();
        if(CollectionUtils.isEmpty(dataList)){
            return new ArrayList<>();
        }
        if(dataList.size()<=limit){
            splitedList.add(dataList);
            return splitedList;
        }
        BigDecimal dataSize = new BigDecimal(dataList.size());
        int count = dataSize.divide(new BigDecimal(limit), RoundingMode.CEILING).toBigInteger().intValue();
        for(int i=0;i<count;i++){
            if(i==count-1){
                splitedList.add(dataList.subList(i*limit, dataSize.intValue()));
            }else{
                splitedList.add(dataList.subList(i*limit,(i+1)*limit));
            }
        }
        return splitedList;
    }
    public static Map<String, String> getFieldValueMap(Object bean, Boolean parent){
        Class<?> cls = null;
        if(parent){
            cls = bean.getClass().getSuperclass();
        }else{
            cls = bean.getClass();
        }
        Map<String, String> valueMap = new HashMap<>();
        Method[] methods = cls.getDeclaredMethods();
        Field[] fields = cls.getDeclaredFields();
        for(Field field: fields){
            try{
                String filedType = field.getType().getSimpleName();
                String filedGetName = parGetName(field.getName());
                if(!checkGetMet(methods,filedGetName)){
                    continue;
                }
                Method fieldGetMet = cls.getMethod(filedGetName, new Class[]{});
                Object fieldVal = fieldGetMet.invoke(bean, new Object[]{});
                String result = null;
                if("Date".equals(filedType)){
                    result = fmtDate((Date) fieldVal);
                }else{
                    if(null!=fieldVal){
                        result = String.valueOf(fieldVal);
                    }
                }
                valueMap.put(field.getName(),result);
            }catch (Exception e){
                continue;
            }
        }
        return valueMap;

    }
    public static String parGetName(String filedName){
        if(null==filedName || "".equals(filedName)){
            return null;
        }
        return "get"+filedName.substring(0,1).toUpperCase() + filedName.substring(1);
    }
    public static boolean checkGetMet(Method[] methods, String fieldGetMet){
        for(Method method: methods){
            if(fieldGetMet.equals(method.getName())){
                return true;
            }
        }
        return false;
    }
    public static String fmtDate(Date date){
        if(null == date){
            return null;
        }
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            return sdf.format(date);
        }catch (Exception e){
            return null;
        }
    }

    public static String positiveMaxAndDecimalPlace(String input, String maxValue, Integer N){
        boolean match = isPositiveMax(input, maxValue);
        if(match){
            if(input.contains(".")){
                String[] inputArr = input.split("\\.");
                int length = inputArr[1].length();
                if(length<=N){
                    return input;
                }else{
                    return inputArr[0] + "." + inputArr[1].substring(0,N);
                }
            }else{
                return input;
            }
        }
        return "";
    }
    public static String REGEX_POSITIVE_FLOAT="^[0-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$|^[1-9]\\d*$";
    public static boolean isPositiveMax(String input, String maxValue){
        boolean match = isMatch(REGEX_POSITIVE_FLOAT, input);
        if(match){
            int resultMax = new BigDecimal(input).compareTo(new BigDecimal(maxValue));
            int resultMin = new BigDecimal(input).compareTo(new BigDecimal("0"));

            if(resultMax<=0 && resultMin>=0){
                return true;
            }
        }
        return false;
    }
    public static boolean isMatch(String regex, CharSequence input){
        return input!=null && input.length()>0 && Pattern.matches(regex,input);
    }
}
